<template>
  <div class="face-recognition">
    <el-card class="camera-card" :body-style="{ padding: '0' }">
      <template #header>
        <div class="card-header">
          <div class="header-left">
            <el-icon size="20"><Camera /></el-icon>
            <span>人脸识别打卡</span>
          </div>
          <div class="time-display">
            <el-icon size="18"><Clock /></el-icon>
            {{ currentTime }}
          </div>
        </div>
      </template>
      
      <div class="camera-container">
        <!-- 视频预览区域 -->
        <video
          ref="videoRef"
          class="camera-preview"
          autoplay
          playsinline
          v-show="!capturedImage && !attendanceResult"
        ></video>
        <!-- 拍照后的预览图 -->
        <img
          v-if="capturedImage && !attendanceResult"
          :src="capturedImage"
          class="capture-preview"
          alt="captured"
        />
        <!-- 拍照遮罩层 -->
        <div class="face-mask" v-show="!capturedImage && !attendanceResult">
          <div class="face-frame"></div>
          <div class="tips">请将面部对准框内</div>
        </div>

        <!-- 打卡结果展示 -->
        <div class="attendance-result-container" v-if="attendanceResult">
          <div class="result-wrapper">
            <div class="result-left">
              <div class="result-animation" :class="{ success: attendanceResult.success }">
                <el-icon v-if="attendanceResult.success" class="result-icon success"><SuccessFilled /></el-icon>
                <el-icon v-else class="result-icon error"><CircleCloseFilled /></el-icon>
              </div>
              <h2 class="result-title">{{ attendanceResult.message }}</h2>
              <el-button type="primary" @click="resetAll" class="return-button">
                {{ attendanceResult.success ? '继续打卡' : '重新尝试' }}
              </el-button>
            </div>
            
            <div class="result-right">
              <!-- 无论成功还是失败都显示基本信息 -->
              <div class="result-details">
                <div class="detail-card">
                  <div class="detail-item" v-if="attendanceResult.empName">
                    <div class="item-label"><el-icon><User /></el-icon> 姓名</div>
                    <div class="item-value">{{ attendanceResult.empName }}</div>
                  </div>
                  <div class="detail-item" v-if="attendanceResult.empNo">
                    <div class="item-label"><el-icon><Ticket /></el-icon> 工号</div>
                    <div class="item-value">{{ attendanceResult.empNo }}</div>
                  </div>
                  <div class="detail-item" v-if="attendanceResult.timestamp">
                    <div class="item-label"><el-icon><Timer /></el-icon> 打卡时间</div>
                    <div class="item-value highlight">{{ attendanceResult.timestamp }}</div>
                  </div>
                  <div class="detail-item" v-if="attendanceResult.isCheckIn !== undefined">
                    <div class="item-label"><el-icon><Place /></el-icon> 打卡类型</div>
                    <div class="item-value">
                      <el-tag :type="attendanceResult.isCheckIn ? 'success' : 'warning'" size="small" effect="dark">
                        {{ attendanceResult.isCheckIn ? '上班打卡' : '下班打卡' }}
                      </el-tag>
                    </div>
                  </div>
                  <div class="detail-item" v-if="attendanceResult.similarity">
                    <div class="item-label"><el-icon><Connection /></el-icon> 识别相似度</div>
                    <div class="item-value">
                      <el-progress 
                        :percentage="attendanceResult.similarity" 
                        :color="getSimilarityColor(attendanceResult.similarity)" 
                        :stroke-width="8"
                        :format="(val) => val.toFixed(1) + '%'"
                      ></el-progress>
                    </div>
                  </div>
                  <div class="detail-item status" v-if="attendanceResult.success">
                    <div class="item-label"><el-icon><InfoFilled /></el-icon> 打卡状态</div>
                    <div class="item-value">
                      <el-tag :type="attendanceResult.statusType" size="small" effect="plain">
                        {{ attendanceResult.statusText }}
                      </el-tag>
                    </div>
                  </div>
                </div>
                
                <!-- 提示信息，无论成功还是失败都显示 -->
                <div class="note-box" v-if="attendanceResult.note">
                  <el-icon><Bell /></el-icon>
                  <span>{{ attendanceResult.note }}</span>
                </div>
                
                <!-- 错误详情，只在失败时显示 -->
                <div class="error-details" v-if="!attendanceResult.success">
                  <el-alert
                    :title="attendanceResult.detail"
                    type="error"
                    :closable="false"
                    show-icon
                    style="margin-top: 10px;"
                  />
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <div class="button-group" v-if="!attendanceResult">
        <template v-if="!capturedImage">
          <el-button 
            type="primary" 
            :icon="VideoCameraFilled"
            @click="startCamera"
            v-if="!cameraStarted"
            class="action-button"
          >
            开启摄像头
          </el-button>
          <el-button 
            type="primary" 
            :icon="Camera"
            @click="takePhoto"
            v-else
            class="action-button"
          >
            拍照打卡
          </el-button>
        </template>
        <template v-else>
          <el-button @click="retake" class="action-button">重新拍照</el-button>
          <el-button 
            type="primary" 
            :loading="uploading"
            @click="submitAttendance"
            class="action-button"
          >
            确认打卡
          </el-button>
        </template>
      </div>
    </el-card>

    <!-- 今日打卡记录 -->
    <!-- <el-card class="record-card">
      <template #header>
        <div class="card-header">
          <div class="header-left">
            <el-icon size="20"><Calendar /></el-icon>
            <span>今日打卡记录</span>
          </div>
        </div>
      </template>
      <el-descriptions :column="1" border>
        <el-descriptions-item 
          label="上班打卡" 
          label-class-name="record-label" 
          class-name="record-content"
        >
          <div class="record-time-wrapper">
            <span class="record-time">{{ todayRecord.checkIn || '未打卡' }}</span>
            <el-tag 
              size="small" 
              :type="todayRecord.checkInStatus === '正常' ? 'success' : 'danger'"
              v-if="todayRecord.checkIn"
            >
              {{ todayRecord.checkInStatus }}
            </el-tag>
          </div>
        </el-descriptions-item>
        <el-descriptions-item 
          label="下班打卡" 
          label-class-name="record-label"
          class-name="record-content"
        >
          <div class="record-time-wrapper">
            <span class="record-time">{{ todayRecord.checkOut || '未打卡' }}</span>
            <el-tag 
              size="small" 
              :type="todayRecord.checkOutStatus === '正常' ? 'success' : 'danger'"
              v-if="todayRecord.checkOut"
            >
              {{ todayRecord.checkOutStatus }}
            </el-tag>
          </div>
        </el-descriptions-item>
      </el-descriptions>
    </el-card> -->
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import { ElMessage } from 'element-plus'
import { Camera, VideoCameraFilled, SuccessFilled, CircleCloseFilled, Calendar, Clock, User, Ticket, Timer, Place, Connection, InfoFilled, Bell } from '@element-plus/icons-vue'
import dayjs from 'dayjs'
import { faceRecognition } from '@/api/attendance/face'
import { useUserStore } from '@/store/user'

const userStore = useUserStore()
const videoRef = ref(null)
const stream = ref(null)
const cameraStarted = ref(false)
const capturedImage = ref(null)
const uploading = ref(false)
const currentTime = ref('')
const attendanceResult = ref(null)

// 今日打卡记录
const todayRecord = ref({
  checkIn: '',
  checkInStatus: '',
  checkOut: '',
  checkOutStatus: ''
})

// 加载用户的打卡记录
const loadUserAttendanceRecord = () => {
  // 如果有登录用户，模拟加载打卡记录
  if (userStore.isAuthenticated && userStore.userInfo) {
    // 这里应该调用API获取当日打卡记录
    // 临时模拟一些数据
    const now = dayjs()
    const hour = now.hour()
    
    if (hour >= 9) {
      todayRecord.value.checkIn = '09:00:00'
      todayRecord.value.checkInStatus = '正常'
    }
    
    if (hour >= 18) {
      todayRecord.value.checkOut = '18:00:00'
      todayRecord.value.checkOutStatus = '正常'
    }
  }
}

// 更新当前时间
const updateCurrentTime = () => {
  currentTime.value = dayjs().format('YYYY-MM-DD HH:mm:ss')
}

// 开启摄像头
const startCamera = async () => {
  try {
    stream.value = await navigator.mediaDevices.getUserMedia({
      video: true,
      audio: false,
    })
    if (videoRef.value) {
      videoRef.value.srcObject = stream.value
      cameraStarted.value = true
    }
  } catch (error) {
    ElMessage.error('无法访问摄像头，请检查权限设置')
    console.error('摄像头访问错误：', error)
  }
}

// 拍照
const takePhoto = () => {
  const video = videoRef.value
  const canvas = document.createElement('canvas')
  canvas.width = video.videoWidth
  canvas.height = video.videoHeight
  const ctx = canvas.getContext('2d')
  ctx.drawImage(video, 0, 0, canvas.width, canvas.height)
  capturedImage.value = canvas.toDataURL('image/jpeg')
}

// 重新拍照
const retake = () => {
  capturedImage.value = null
}

// 将Base64图片转换为二进制Blob
const base64ToBlob = (base64Data) => {
  // 移除Data URL前缀
  const base64WithoutPrefix = base64Data.substr(base64Data.indexOf(',') + 1)
  const byteString = atob(base64WithoutPrefix)
  const ab = new ArrayBuffer(byteString.length)
  const ia = new Uint8Array(ab)
  
  for (let i = 0; i < byteString.length; i++) {
    ia[i] = byteString.charCodeAt(i)
  }
  
  return new Blob([ab], { type: 'image/jpeg' })
}

// 提交打卡
const submitAttendance = async () => {
  if (!capturedImage.value) {
    ElMessage.warning('请先拍照')
    return
  }

  uploading.value = true
  try {
    // 将图片转换为Blob对象
    const imageBlob = base64ToBlob(capturedImage.value)
    
    // 创建FormData对象
    const formData = new FormData()
    formData.append('file', imageBlob, 'face.jpg')
    
    // 调用人脸识别打卡接口
    const response = await faceRecognition(formData)
    
    // 处理响应结果
    if (response.data) {
      // 获取后端返回的数据
      const resData = response.data
      
      // 检查状态是否为打卡成功（status为success）
      const isSuccess = resData.status === 'success'
      
      // 格式化时间戳（从ISO格式转为易读格式）
      const timestampObj = dayjs(resData.timestamp)
      const formattedTime = timestampObj.format('YYYY-MM-DD HH:mm:ss')
      
      // 获取小时，用于判断是上班还是下班
      const hour = timestampObj.hour()
      const isCheckIn = hour < 12
      
      // 准备打卡状态信息
      let statusType = isSuccess ? 'success' : 'danger'
      let statusText = isSuccess ? '正常' : '打卡失败'
      let note = ''
      
      // 根据message判断打卡状态并设置提示
      if (resData.message && resData.message.includes('重复打卡')) {
        statusType = 'info'
        statusText = '重复打卡'
        note = resData.message
      } else if (isSuccess && isCheckIn) {
        // 上班打卡状态判断
        if (hour >= 9) {
          statusType = 'warning'
          statusText = '迟到'
          note = '您已迟到，请注意今后准时打卡。'
        } else if (hour < 7) {
          statusType = 'info'
          statusText = '早到'
          note = '您来得真早！'
        }
      } else if (isSuccess && !isCheckIn) {
        // 下班打卡状态判断
        if (hour < 18) {
          statusType = 'warning'
          statusText = '早退'
          note = '您已早退，请确认工作是否已完成。'
        } else if (hour >= 20) {
          statusType = 'info'
          statusText = '加班'
          note = '辛苦了，请注意休息！'
        }
      }
      
      // 设置打卡结果对象
      attendanceResult.value = {
        success: isSuccess,
        message: resData.message || (isSuccess ? '打卡成功' : '打卡失败'),
        detail: isSuccess ? '人脸识别成功' : resData.message || '人脸识别失败，请重试',
        empName: resData.name || userStore.userInfo?.name || '',
        empNo: resData.employeeNo || userStore.userInfo?.employeeNo || '',
        timestamp: formattedTime,
        similarity: resData.similarity ? resData.similarity * 100 : 0, // 转换为百分比
        isCheckIn,
        statusType,
        statusText,
        note: resData.message || note // 优先显示后端返回的消息
      }
      
      // 若相似度低于阈值但大于0，显示相似度不足提示
      if (resData.similarity > 0 && resData.similarityThreshold && resData.similarity < resData.similarityThreshold) {
        attendanceResult.value.note = `人脸相似度${(resData.similarity * 100).toFixed(1)}%低于系统阈值${(resData.similarityThreshold * 100).toFixed(1)}%`
        attendanceResult.value.statusText = '相似度不足'
        attendanceResult.value.statusType = 'danger'
      }
      
      // 更新今日记录
      if (isSuccess) {
        // 根据时间判断是上班还是下班打卡
        if (isCheckIn) { // 12点前为上班打卡
          todayRecord.value.checkIn = timestampObj.format('HH:mm:ss')
          todayRecord.value.checkInStatus = statusText
        } else { // 12点后为下班打卡
          todayRecord.value.checkOut = timestampObj.format('HH:mm:ss')
          todayRecord.value.checkOutStatus = statusText
        }
      }
    } else {
      // 处理错误响应
      attendanceResult.value = {
        success: false,
        message: '打卡失败',
        detail: '服务器返回数据格式不正确'
      }
    }
  } catch (error) {
    console.error('打卡错误:', error)
    attendanceResult.value = {
      success: false,
      message: '打卡失败',
      detail: error.message || '请求失败，请检查网络连接'
    }
  } finally {
    uploading.value = false
    // 关闭摄像头
    if (stream.value) {
      stream.value.getTracks().forEach(track => track.stop())
      stream.value = null
      cameraStarted.value = false
    }
  }
}

// 相似度颜色计算
const getSimilarityColor = (percentage) => {
  if (percentage < 70) return '#f56c6c'
  if (percentage < 85) return '#e6a23c'
  return '#67c23a'
}

// 重置所有状态
const resetAll = () => {
  capturedImage.value = null
  attendanceResult.value = null
  startCamera()
}

// 组件挂载时
onMounted(() => {
  updateCurrentTime()
  // 加载用户打卡记录
  loadUserAttendanceRecord()
  // 每秒更新时间
  const timer = setInterval(updateCurrentTime, 1000)
  onUnmounted(() => {
    clearInterval(timer)
    // 关闭摄像头
    if (stream.value) {
      stream.value.getTracks().forEach(track => track.stop())
    }
  })
})
</script>

<style scoped lang="scss">
.face-recognition {
 // display: grid;
 // grid-template-columns: 2fr 1fr;
 // gap: 20px;
 width: 75%;
 margin: 0 auto;

  .camera-card {
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08);
    border-radius: 16px;
    overflow: hidden;
    transition: all 0.3s ease;
    
    &:hover {
      box-shadow: 0 15px 35px rgba(0, 0, 0, 0.12);
      transform: translateY(-5px);
    }
    
    .card-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 18px 24px;
      background: linear-gradient(135deg, #d4eaf7, #a5d3ed);
      color: #2c3e50;
      border-radius: 12px;
      margin: 0 15px;
      margin-top: 15px;
      
      .header-left {
        display: flex;
        align-items: center;
        gap: 12px;
        font-size: 20px;
        font-weight: 600;
        
        .el-icon {
          background: rgba(41, 128, 185, 0.15);
          width: 36px;
          height: 36px;
          border-radius: 50%;
          display: flex;
          align-items: center;
          justify-content: center;
          color: #2980b9;
        }
      }
      
      .time-display {
        display: flex;
        align-items: center;
        gap: 8px;
        font-size: 16px;
        background-color: rgba(255, 255, 255, 0.6);
        padding: 8px 15px;
        border-radius: 30px;
        backdrop-filter: blur(5px);
        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
        color: #2c3e50;
        
        .el-icon {
          color: #2980b9;
        }
      }
    }

    .camera-container {
      position: relative;
      width: 100%;
      height: 500px;
      background: #121212;
      overflow: hidden;

      .camera-preview,
      .capture-preview {
        width: 100%;
        height: 100%;
        object-fit: cover;
      }

      .face-mask {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background: rgba(0, 0, 0, 0.4);
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;

        .face-frame {
          width: 280px;
          height: 280px;
          border: 4px solid rgba(52, 152, 219, 0.8);
          border-radius: 50%;
          margin-bottom: 24px;
          box-shadow: 0 0 30px rgba(52, 152, 219, 0.5);
          position: relative;
          animation: pulse 2.5s infinite;
          
          &::after {
            content: '';
            position: absolute;
            top: -10px;
            left: -10px;
            right: -10px;
            bottom: -10px;
            border: 2px dashed rgba(52, 152, 219, 0.4);
            border-radius: 50%;
            animation: rotate 15s linear infinite;
          }
        }

        .tips {
          color: #fff;
          font-size: 18px;
          font-weight: 500;
          text-shadow: 0 2px 8px rgba(0, 0, 0, 0.7);
          background: rgba(0, 0, 0, 0.3);
          padding: 10px 20px;
          border-radius: 30px;
          backdrop-filter: blur(5px);
        }
      }
      
      .attendance-result-container {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        background: rgba(255, 255, 255, 0.97);
        padding: 20px;
        text-align: center;
        overflow-y: auto;
        
        .result-wrapper {
          display: flex;
          flex-direction: row;
          justify-content: space-between;
          align-items: flex-start;
          width: 100%;
          max-width: 800px; /* 增加最大宽度以适应横向布局 */
          
          .result-left {
            flex: 0 0 220px; /* 固定宽度 */
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            padding: 0 15px;
            
            .result-animation {
              margin: 15px 0;
              width: 120px;
              height: 120px;
              background: #e74c3c;
              border-radius: 50%;
              display: flex;
              justify-content: center;
              align-items: center;
              animation: zoomIn 0.5s cubic-bezier(0.175, 0.885, 0.32, 1.275);
              box-shadow: 0 10px 30px rgba(231, 76, 60, 0.3);
              
              &.success {
                background: #2ecc71;
                box-shadow: 0 10px 30px rgba(46, 204, 113, 0.3);
              }
              
              .result-icon {
                font-size: 70px;
                color: white;
              }
            }
            
            .result-title {
              font-size: 22px;
              font-weight: 600;
              margin-bottom: 20px;
              color: #2c3e50;
            }
            
            .return-button {
              padding: 10px 25px;
              font-size: 15px;
              background: linear-gradient(135deg, #3498db, #2980b9) !important;
              border: none !important;
              color: white !important;
              border-radius: 30px !important;
              transition: all 0.3s ease;
              
              &:hover {
                transform: translateY(-3px);
                box-shadow: 0 10px 20px rgba(41, 128, 185, 0.3);
              }
              
              &:active {
                transform: translateY(0);
              }
            }
          }
          
          .result-right {
            flex: 1;
            display: flex;
            flex-direction: column;
            align-items: stretch;
            max-width: 550px;
            
            .result-details {
              width: 100%;
              background: #f9f9fa;
              border-radius: 12px;
              padding: 15px;
              box-shadow: 0 5px 15px rgba(0, 0, 0, 0.05);
              
              .detail-card {
                display: grid;
                grid-template-columns: repeat(2, 1fr);
                gap: 12px;
                margin-bottom: 15px;
                
                .detail-item {
                  padding: 10px;
                  background-color: rgba(255, 255, 255, 0.8);
                  border-radius: 8px;
                  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.03);
                  transition: all 0.3s;
                  
                  &:hover {
                    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
                    transform: translateY(-2px);
                  }
                  
                  &.status {
                    grid-column: span 2;
                    background-color: rgba(241, 245, 249, 0.8);
                  }
                  
                  .item-label {
                    display: flex;
                    align-items: center;
                    gap: 5px;
                    color: #7f8c8d;
                    font-size: 14px;
                    margin-bottom: 6px;
                    
                    .el-icon {
                      font-size: 15px;
                      color: #3498db;
                    }
                  }
                  
                  .item-value {
                    font-size: 15px;
                    color: #34495e;
                    font-weight: 500;
                    
                    &.highlight {
                      color: #e67e22;
                      font-size: 16px;
                      letter-spacing: 1px;
                      font-family: 'Courier New', monospace;
                    }
                    
                    .el-tag {
                      font-weight: 600;
                      padding: 3px 8px;
                    }
                  }
                }
              }
              
              .note-box {
                display: flex;
                align-items: center;
                gap: 8px;
                background-color: #fef9e7;
                padding: 10px 14px;
                border-radius: 8px;
                border-left: 4px solid #f39c12;
                font-size: 14px;
                color: #926c0b;
                
                .el-icon {
                  font-size: 16px;
                  color: #f39c12;
                }
              }
            }
            
            .error-details {
              width: 100%;
              
              :deep(.el-alert) {
                border-radius: 8px;
                
                .el-alert__title {
                  font-size: 15px;
                  line-height: 1.5;
                }
                
                .el-alert__icon {
                  font-size: 18px;
                }
              }
            }
          }
        }
      }
    }

    .button-group {
      padding: 20px;
      display: flex;
      justify-content: center;
      gap: 25px;
      background: #f8f9fa;
      
      .action-button {
        padding: 12px 30px;
        font-size: 16px;
        background: linear-gradient(135deg, #3498db, #2980b9) !important;
        border: none !important;
        color: white !important;
        border-radius: 30px !important;
        transition: all 0.3s ease;
        display: flex;
        align-items: center;
        gap: 8px;

        &:hover {
          transform: translateY(-3px);
          box-shadow: 0 10px 20px rgba(41, 128, 185, 0.3);
        }

        &:active {
          transform: translateY(0);
        }
        
        &:not(.el-button--primary) {
          background: white !important;
          color: #2c3e50 !important;
          border: 1px solid #e0e0e0 !important;
          
          &:hover {
            background: #f5f5f5 !important;
            box-shadow: 0 8px 15px rgba(0, 0, 0, 0.05);
          }
        }
      }
    }
  }

  .record-card {
    box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08);
    border-radius: 16px;
    height: fit-content;
    transition: all 0.3s ease;
    
    &:hover {
      box-shadow: 0 15px 35px rgba(0, 0, 0, 0.12);
      transform: translateY(-5px);
    }
    
    .card-header {
      display: flex;
      align-items: center;
      gap: 10px;
      margin-bottom: 15px;
      padding: 18px 24px;
      background: linear-gradient(135deg, #d4eaf7, #a5d3ed);
      color: #2c3e50;
      border-radius: 12px;
      margin: 0 15px;
      margin-top: 15px;
      
      .header-left {
        display: flex;
        align-items: center;
        gap: 12px;
        font-size: 18px;
        font-weight: 600;
        
        .el-icon {
          background: rgba(41, 128, 185, 0.15);
          width: 36px;
          height: 36px;
          border-radius: 50%;
          display: flex;
          align-items: center;
          justify-content: center;
          color: #2980b9;
        }
      }
    }
    
    :deep(.el-descriptions__label) {
      width: 120px;
      background-color: #f5f7fa;
      padding: 18px;
      font-weight: 600;
      color: #2c3e50;
    }
    
    :deep(.el-descriptions__content) {
      padding: 18px;
    }
    
    .record-time-wrapper {
      display: flex;
      align-items: center;
      gap: 12px;
      
      .record-time {
        font-size: 18px;
        font-weight: 500;
        color: #34495e;
        font-family: 'Courier New', monospace;
      }
      
      .el-tag {
        padding: 6px 12px;
        border-radius: 20px;
        font-weight: 600;
      }
    }
  }
}

@keyframes pulse {
  0% {
    box-shadow: 0 0 0 0 rgba(52, 152, 219, 0.7);
  }
  70% {
    box-shadow: 0 0 0 20px rgba(52, 152, 219, 0);
  }
  100% {
    box-shadow: 0 0 0 0 rgba(52, 152, 219, 0);
  }
}

@keyframes rotate {
  0% {
    transform: rotate(0deg);
  }
  100% {
    transform: rotate(360deg);
  }
}

@keyframes zoomIn {
  from {
    opacity: 0;
    transform: scale(0.5);
  }
  to {
    opacity: 1;
    transform: scale(1);
  }
}

@media screen and (max-width: 1200px) {
  .face-recognition {
    grid-template-columns: 1fr;
  }
}

@media screen and (max-width: 768px) {
  .face-recognition {
    width: 95%;
    
    .camera-container {
      height: 400px;
    }
    
    .face-mask .face-frame {
      width: 220px;
      height: 220px;
    }
    
    .attendance-result-container {
      padding: 15px;
      
      .result-wrapper {
        flex-direction: column;
        align-items: center;
        
        .result-left {
          flex: none;
          margin-bottom: 20px;
          width: 100%;
          
          .result-animation {
            width: 100px;
            height: 100px;
          
            .result-icon {
              font-size: 60px;
            }
          }
          
          .result-title {
            font-size: 20px;
            margin-bottom: 15px;
          }
        }
        
        .result-right {
          width: 100%;
          max-width: 100%;
          
          .result-details {
            padding: 12px;
            
            .detail-card {
              grid-template-columns: 1fr;
              gap: 10px;
              
              .detail-item.status {
                grid-column: span 1;
              }
            }
          }
        }
      }
    }
    
    .button-group {
      flex-direction: column;
      
      .action-button {
        width: 100%;
      }
    }
  }
}

// 覆盖 el-button 的默认样式
:deep(.el-button--primary) {
  &.is-loading {
    background: linear-gradient(135deg, #3498db, #2980b9) !important;
    opacity: 0.8;
    
    &::before {
      background-color: rgba(255, 255, 255, 0.35);
    }
  }
}

.btn-primary {
  background: linear-gradient(to right, #3498db, #2980b9);
  color: white;
  border: none;
  padding: 12px 30px;
  font-size: 18px;
  border-radius: 30px;
  cursor: pointer;
  transition: all 0.3s ease;
  box-shadow: 0 4px 15px rgba(41, 128, 185, 0.3);
  
  &:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 20px rgba(41, 128, 185, 0.4);
  }
  
  &:active {
    transform: translateY(1px);
    box-shadow: 0 2px 10px rgba(41, 128, 185, 0.3);
  }
}

.btn-secondary {
  background: rgba(255, 255, 255, 0.9);
  color: #2980b9;
  border: 1px solid #a5d3ed;
  padding: 12px 30px;
  font-size: 18px;
  border-radius: 30px;
  cursor: pointer;
  transition: all 0.3s ease;
  box-shadow: 0 4px 15px rgba(165, 211, 237, 0.3);
  
  &:hover {
    background: rgba(213, 234, 247, 0.9);
    transform: translateY(-2px);
    box-shadow: 0 6px 20px rgba(165, 211, 237, 0.4);
  }
  
  &:active {
    transform: translateY(1px);
    box-shadow: 0 2px 10px rgba(165, 211, 237, 0.3);
  }
}
</style> 